//
// Created by Tan Ke on 2024/1/2.
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct WordItem {
    char* word;
    int cnt;
};

char* mostCommonWord(char* paragraph, char** banned, int bannedSize)
{
    struct WordItem** wordItemMap = (struct WordItem**)malloc(sizeof(struct WordItem*) * 4096);
    int wordItemMapLen = 0;
    int index = 0;

    for(index = 0; index < strlen(paragraph); index ++) {
        if (paragraph[index] == ' ' || paragraph[index] == ',' || paragraph[index] == '?' ||
            paragraph[index] == '\'' || paragraph[index] == ';' || paragraph[index] == '\"' ||
            paragraph[index] == '!' || paragraph[index] == '.') {
            continue;
        } else {
            break;
        }
    }

    char tmp[4096] = {0};
    int tmpLen = 0;

    while (index <= strlen(paragraph)) {
        if (paragraph[index] != ' ' && paragraph[index] != ',' && paragraph[index] != '?' &&
            paragraph[index] != '\'' && paragraph[index] != ';' && paragraph[index] != '\"' &&
            paragraph[index] != '!' && paragraph[index] != '.' && paragraph[index] != 0) {
            if (paragraph[index] >= 'A' && paragraph[index] <= 'Z') {
                tmp[tmpLen] = paragraph[index] - 'A' + 'a';
            } else {
                tmp[tmpLen] = paragraph[index];
            }
            tmpLen += 1;
        } else {
            int isBannedWord = 0;
            if (tmpLen > 0) {
                for (int m = 0; m < bannedSize; m ++) {
                    if (strlen(banned[m]) == tmpLen && strcmp(banned[m], tmp) == 0) {
                        isBannedWord = 1;
                    }
                }
                if (isBannedWord == 0) {
                    int isExist = 0;
                    for (int n = 0; n < wordItemMapLen; n ++) {
                        if (strlen(wordItemMap[n]->word) == tmpLen && strcmp(wordItemMap[n]->word, tmp) == 0) {
                            isExist = 1;
                            wordItemMap[n]->cnt += 1;
                        }
                    }
                    if (isExist == 0) {
                        struct WordItem *item = (struct WordItem *) malloc(sizeof(struct WordItem));
                        item->word = (char *) malloc(sizeof(char) * (tmpLen + 1));
                        memset(item->word, 0, (tmpLen + 1));
                        memcpy(item->word, tmp, tmpLen);
                        item->cnt = 1;
                        wordItemMap[wordItemMapLen] = item;
                        wordItemMapLen += 1;
                    }
                }
                memset(tmp, 0, 4096);
                tmpLen = 0;
            }
        }
        index += 1;
    }

#if 0

    for (int i = 0; i < wordItemMapLen; i ++) {
        printf("%s : %d\n", wordItemMap[i]->word, wordItemMap[i]->cnt);
    }

#endif

    int maxWordCntIndex = 0;

    for (int i = 0; i < wordItemMapLen; i ++) {
        if (wordItemMap[i]->cnt > wordItemMap[maxWordCntIndex]->cnt) {
            maxWordCntIndex = i;
        }
    }

    return wordItemMap[maxWordCntIndex]->word;
}

int main(void)
{
    char* paragraph = "Bob hit a ball, the hit BALL flew far after it was hit";
    char** banned = (char**)malloc(sizeof(char*) * 1);
    banned[0] = (char*)malloc(sizeof(char) * 4);
    memset(banned[0], 0, 4);
    strcpy(banned[0], "hit");

    printf("%s\n", mostCommonWord(paragraph, banned, 1));
    return 0;
}
